package com.larry.java3;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @ProjectName jvm_dc
 * @Author larry
 * @Date 14:47 2021/7/30
 * @Description 手写自定义类加载器
 **/
public class UserDefineClassLoader extends ClassLoader{

    private String rootPath;

    public UserDefineClassLoader(String rootPath) {
        this.rootPath = rootPath;
    }

    @Override
    protected Class<?> findClass(String s) throws ClassNotFoundException {
        //转换为以文件路径表示的文件
        String classToFilePath = classToFilePath(s);
        //或者指定路径的class文件二进制流数据
        byte[] bytes = getBytesFromPath(classToFilePath);
        //自定义Classloader内部调用defineclass()
        return defineClass(s, bytes,0, bytes.length);
    }

    private byte[] getBytesFromPath(String classToFilePath) {


        FileInputStream fileInputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try {
            fileInputStream = new FileInputStream(classToFilePath);
            byteArrayOutputStream = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            int len;

            while ((len = fileInputStream.read(buffer))  != -1) {
                byteArrayOutputStream.write(buffer,0,len);
            }

            return byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileInputStream != null){
                    fileInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (byteArrayOutputStream != null){
                    byteArrayOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;

    }

    private String classToFilePath(String s) {
        return rootPath + "\\" + s.replace(".","\\") + ".class";
    }

    public static void main(String[] args) {
        try {
            //C:\Users\larry\IdeaProjects\jvm_dc\bytecode\src\main\java\com\larry\java3
            UserDefineClassLoader loader = new UserDefineClassLoader("C:\\Users\\larry\\IdeaProjects\\jvm_dc\\bytecode\\src\\main\\java");
            Class<?> user = loader.findClass("com.larry.java3.User");
            System.out.println(user);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
        }
    }
}
